home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 51
/
Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso
/
-in_the_mag-
/
banging_the_metal
/
charmode.text
next >
Wrap
Text File
|
2000-01-01
|
23KB
|
400 lines
CHARMODE DEMO
An Amiga Character mapped display mode generated by Custom Chips
FEATURES Same-field update of the entire screen with beam avoidance
Support for up to 640 x 287 resolution (currently PAL only)
font support for up to 256 characters each up to 16 pixels tall
Support for dynamic font changes from one field to the next
Remaps screens encoded as one byte per character into Amiga bitplane graphics.
This demo uses the copper to generate a custom screen mode and convert
character codes into graphic patterns from a font, by programming the blitter.
All processing is performed by the custom chips. All the CPU need do is write a
small table of character codes to determine the new display. Almost all the
main CPU time is available for other purposes.
This document is edited from the 'internal' development documentation, and
should be read in conjunction with the fuller explanations in Amiga Format.
CharMode is intended for use in emulators for vintage computers and terminals
with character-mapped displays. These include TRS-80 (64 x 16 characters of 8 x
12 pixels, on a 512 x 192 pixel grid), CP/M, IBM MDA and most ASCII terminals
(typically 80 x 24 or 80 x 25 characters), PET (40x25 8 x 8 characters), ZX80
and ZX81 (32 x 24 characters), MSX, Dragon, Atari, etc.
It uses a font of 256 characters, each eight pixels wide and up to 16 pixels
tall, with one byte, left justified, in each pattern WORD. Thus the font takes
256 (characters) x 32 (bytes) = 8K. If the character height is less than 16
pixels the rendered character is truncated at the bottom.
Dynamic font changes are supported on a per-field basis by writing the changed
data to the corresponding font words. These need to be unpacked as the font
must use one WORD per character line (as it's a 16 bit blitter). Automatic
unpacking of 8 x 8 fonts is implemented.
Supported Screen formats:
Char Width Char Height Chars/Row Chars/Col Prime Time Characters
8 8 80 24 58 1920
8 8 80 25 47 2000
8 8 80 28 17 2240
8 8 80 29 6 2320
8 10 80 24 14 1920
8 12 80 20 20 1600
8 16 80 16 8 1280
8 8 64 32 40 2048
8 8 64 35 15 2240
8 16 64 16 40 1024
8 12 64 16 52 1024
8 10 64 25 52 1600
Those formats are high resolution. Thsse are some low resolution formats:
8 8 40 24 106 960
8 8 40 25 97 1000
8 8 40 32 40 1280
8 10 40 24 62 960
8 10 40 25 52 1000
8 12 40 16 108 640
8 16 40 16 40 640
8 8 32 24 106 768
8 8 32 32 40 1024
8 10 32 24 62 768
8 12 32 20 60 640
8 16 32 16 40 512
These are all tested examples. Many other formats are possible; in general the
code expects widths of 32, 40, 64 or 80 characters and from 16 to 32 lines.
Other values may require additional ad hoc code to fine-tune display timing.
Notes on the formats
Char Heights are in Pixels. All character widths are eight pixels. Line widths
must be even as we're using a 16 bit chip set. Prime Time is the number of scan
lines of time available from the start of the field before the copper starts to
blit character patterns. Normally this is padded by adding HeadLines - scan
lines when the display is visible but not part of the blitted character map. 25
undisplayed scans are available at the start of each field. In practice one
additional line time should be allowed for the copper initialisation at the
start of each field.
It's advantageous to allow more lines, but this moves the character mapped
screen portion down the display. With 2000 8 x 8 pixel characters on-screen (25
lines of 80 columns) up to 87 lines of heading are supported (in PAL mode the
line limit is 287, and 25 x 8 = 200 pixels for the character map) and this
gives the latest allowable character map on the screen, with the maximum time
for updates at the start of the field - around 5500 microseconds.
High values of Prime Time indicate that the display could be moved higher up
the screen (rather than extending to display line 287) while still allowing
VBLANK updates. If the Prime Time value is low it may be necessary to start the
CPU update as the blitter finishes updating the last character and the last
line begins to be displayed - this boosts the available time from a
near-impossible eight lines to 24 with 80 x 16 8 x 16 characters.
Beam Avoidance is assured by timing the blits so that the last blit for the
last line is complete before that row of characters starts to be displayed. It
follows that character map or font updates can be performed at any time from
the start of display of that line, rather than top of frame. This is more
complicated than waiting for VBLANK - it requires a copper interrupt - but
gives more time for interrupt response and update before the data is needed for
the next field.
These modes are expected to be used on machines with fast memory, as much of
the chip RAM bus bandwidth is consumed by the copper and blitter updates. It
makes sense to keep the master copy of the current screen in fast RAM. If the
fast memory is more than twice the speed of chip RAM - as in the case of A3000
and A4000 systems, and expanded machines with processor-local 32 bit memory on
the CPU card - it is generally worth keeping a second copy of the last screen
written in fast RAM, and only writing changed information at the start of a
field. A similar technique can be used for font updates, as it's rare that the
entire font will change every field.
Word or long word transfers are important to ensure quick enough updates from
fast RAM to chip RAM. It may be worth adding a blitter pass to expand the font
from byte to word format. The trade-off is the extra chip bandwidth required
against the reduced time that the CPU spends waiting for writes to Chip RAM to
be completed.
HiRes character updates are performed with the BLITTER_NASTY bit set, consuming
all available processor memory cycles as each character is generated, but the
processor still gains access to memory at least four times per scan line as
WAITs are interspersed between the blits. There's much more bandwidth available
just before and after the vertical blank, and that is when writes to the font
and character map should be performed. Not only does the processor get more
time then, it's the ideal point at which to copy the emulated screen to the
real screen hardware to minimise delay and ensure field synchronisation, with
all characters changed in a given emulated field guaranteed to appear in the
next display.
The blitter and copper instructions used are compatible with all Amigas from
the original OCS through ECS to AGA. 30 KHz VGA monitor support could be but is
not included. Scan doubling would require lines to be generated twice as
quickly.
The current code is designed for a 15 KHz PAL display and would need changes
for other modes. It was developed and tested with Amiga Qdos, and is intended
to be used in custom screens on the Amiga, with ownership of the blitter
throughout updates, only relinquishing it when the emulator screen is swapped
off or paused.
The code sets out to centre the display vertically and horizontally, while
ensuring plenty of free time at the start of each field for updates from the
CPU. In total, the display must be at least 192 pixels tall and start by scan
64 - well within limits of all Amiga chip sets.
Extra lines can be added at the top of the display. These are not used for the
character map but can be written (albeit slowly) by the processor and are ideal
for headings, menus and emulator status. They are added at the top to give the
blitter more time to generate the field without beam splitting. In order to
leave some bandwidth for the CPU, even in the middle of the bitmap, high
resolution 8 x 8 pixel character blits need slightly more blitter and copper
DMA time than they take to be output, so generation must start earlier.
For instance a display of the maximum number of characters (2320, in 80 columns
and 29 rows) requires at least 50 display scan lines of head-start to ensure
that all character lines are regenerated ahead of the beam. This comes close to
the limit of 29 x 8 = 232 pixel lines of text and 55 for the HeadLines. No more
than 30 line times are available at the start of the field for CPU screen
updates - less than 2 milliseconds.
That is not long, even when there's only about two and a quarter K that needs
to be written to update the entire screen. Allow for interrupt latency (up to 4
lines) & remember that Chip RAM bandwidth available to the CPU may be as low as
1.8 Mb per second on many Amigas, even without DMA contention, so that a full
screen character write can take up to 20 scan lines to be completed! At best,
on Commodore 68030 or Phase Five accelerators, 5 lines are needed.
As of version 0.13, the code was not optimised to work out the best wait
between blits and ideal start line for LowRes characters, or HiRes characters
more than 12 pixels high. It may finish blitting long before the last line,
indicating that more time could be available between blits or (possibly) they
could all start later. The ad-hoc code to work out Prime Time only attempts to
maximise it for less tall characters, where the copper overhead for each blit
is more significant and keeping up with the beam is problematic.
COPPER LIST COMPILER
The Copper list is generated by a SuperBASIC program, the Copper List Compiler.
This contains instructions to do the following things 50 times per second:
(1) Set up a custom bitplane display centred on the PAL screen
(2) Expand an 8 x 8 pixel character font into internal format for blitting
(3) Convert an 8 bit table of character codes into pattern blit instructions
(4) Generate the new display by blitting one pattern for each character code
The Copper list Compiler (CharMode_bas) also calculates and displays the number
of the line on which blitting will start, so that the user can ensure CPU
updates will occur in time. Extra lines can be allocated to ensure beam
avoidance. It can include instructions to show the time taken for each activity
by colour-coding the screen in stripes.
The Compiler has been tested on systems ranging from AGA A4000/060 to ECS A500.
All supporting software is PD. It uses SuperBASIC extensions, all of which are
provided with the exception of Toolkit 2 or PD Toolkit. The BOOT program
assumes that Toolkit 2 is available.
Compilation parameters
To generate a custom copper list for a given display format, change the
assignment of these variables at the start of AutoChar_bas.
ShowTime 0 or 1 Flag - set to get coloured stripes on screen
Green: extracting even characters from the character map to the Copper List.
Blue: extracting even characters from the character map to the Copper List.
Red: ascending pass blitter unpack. CPU update can overlap if working forwards
Purple: descending pass of blitter unpack - changes in this phase get displayed
one field late - but blitter is not BUSY so CPU writes go at reasonable
speed.
Dark Blue: rendering characters by blitting patterns from the font. This area
should end before the start of display of the last character line.
Blitfont 0 or 1 Flag - expand 8 x 8 font to 8 x 16 automatically every field?
This is too slow to be feasible with a full screen HighRes display, but can be
performed on a partial-height screen if HeadLines are allocated to give time
for the update at the start of each field. It only works with an 8 x 8
character font.
BlitChars 0 or 1 Flag - include code to expand the CharMap?
Otherwise to change a character you need to poke a word giving the base
address of its pattern in the font into the copper list at a corresponding
position. For instance with an 8 pixel tall font, to display character 65
(ASCII "A") you'd poke 65 x16 (bytes per character) into the copper list.
Multiply by 32 for characters up to 16 pixels tall.
The characters are controlled by words between the pointers FirstCharMove and
LastCharMove (both absolute addresses). The first character's font pointer
word is at FirstCharMove. The second is FOUR BYTES EARLIER. The third is 20
bytes on from the first, the fourth is at offset 16 from the start, and so on:
FirstCharMove,FirstCharMove-4, 20, 16, 40, 36, ... LastCharMove+4,LastCharMove
CharHeight% 1 to 16 Height of each character in pixels
Typically 8, 9, 10, 12 or 16. fonts 8, 9 and 16 pixels high are
included. The tallest uses IBM PC character codes, the shortest follows
the MGT SAM convention with duplicates of the ASCII set 32-127 in the
second half (ignoring bit 7) while the nine pixel high one is the 256
character Minerva Qdos set.
CharWidth% 8 THIS CANNOT BE CHANGED!
CharColumns% 32,40,64,80 Number of characters on each display line
High Resolution (70 nS pixel) mode is used for widths over 40
characters (320 pixels)
Other even values also work but may not be optimally timed.
Odd values are not allowed, for reasons of 16 bit alignment.
CharLines% 1 to 35 Number of character lines
HeadLines% 0 to 279 Number of pixel lines in bitplane BEFORE characters start
These is an interaction between these two. When a large number of CharLines% is
chosen, the blitter needs more time to render them, so HeadLines% may be
required to delay the display of characters until the blitter has had time to
render them. This has the unfortunate effect of pushing the display down the
screen, but does give some extra space for menus or headings at the top.
There's no reason why the HeadLines should not be in a different mode, although
the compiler assumes one bit map for the characters and heading. The important
thing is to delay output of the characters to give time for CPU update of the
CharMap and font, Copper and Blitter unpacking of those into more Copper and
Blitter data, and ensure that rendering of the characters still precedes the
beam!
The compiled Copper list uses absolute addresses but can be relocated to any
64K boundary by adjusting the pointers to PAGE, set at or fairly near the
start. The page alignment is vital because the font must be at the start of a
page so that it can be efficiently indexed with scaled character codes from
zero in the low word of blitter pointers.
Compiler Limitations
This section discusses the limits imposed by the choice of data structures and
design of the Copper List Compiler. These are practical limits associated with
the current implementation on OCS Amiga hardware, rather than theoretical
limits of the CharMode principle.
The current version of the compiler (0.13) only supports dynamic font
unpacking for 8 x 8 character fonts. This suits all the machines (Atari, C64,
MSX, Sinclair ZX-81) which require it. Taller fonts are supported but not
dynamic. In other words modified bytes must be written unpacked (16 bits wide,
left justified). The unpacking consumes quite a lot of blitter time - too much
for full-screen HiRes display. It's fine for displays of up to about 1000
characters, and again that corresponds to the displays we'd want to emulate.
The compiler assumes a 50 Hertz PAL display with up to 287 lines. NTSC and
Double-scan VGA modes could be supported but with reduced performance as the
display pushes out more pixels for a given amount of time available for blitter
activity.
Characters must be eight pixels wide. This is a consequence of the way the
blitter is used to render two characters at once. Peter Corlett had this key
idea, without which the code would be much slower as it would need to mask and
generate one character at a time. It's easy to render 16-pixel wide characters
at fair speed with simple un-masked blits, but in general other widths would be
rendered much more slowly.
These modes all use a single bitplane and two colours. This minimise Amiga Chip
RAM and bandwidth requirements, and suits the old monochrome screens which were
standard for character-mapped modes.
Colour character-mapped modes could supported analogously but need a different
approach as all output goes to a single bitplane. This can be re-coloured
efficiently with a copper list, but the extra copper instructions to change
colours must be fitted around the existing heavy copper activity. Attribute
plus bitplane graphics (as on C64, MSX, SAM, Spectrum and TI-99/4) can be
emulated similarly, although the heavy copper-blitting characteristic of
character-mapped emulation is not needed in such cases.
Simon N Goodwin, simon@studio.woden.com, January 2000
DATA STRUCTURES
The CharMode data structures start on a 64K boundary in Chip memory. font and
Bitplane data is guaranteed to fit in the first 64K, while the Copper list will
start there but may extend into the next 64K page.
font size: 8K (allocated - may not be all used)
If LoRes 8 x 8 characters are in use the font is stored in two forms. At
offset +4096 there is a 2K packed byte image, as would be used in an 8 bit
micro, with 8 x 256 bytes per character. This is immediately preceded by a
blitter-generated 4K version, identical but that each packed byte is followed
by a zero byte for convenience when performing 16 bit blits. The packed data is
followed by 2K of unused space. To change the font, the CPU simply writes the
changes into the packed area and they are unpacked and used automatically by
the copper and blitter.
If HiRes characters are in use or the character height is not eight, the font
is only stored in unpacked form with 16 by 16 bits per character. Again valid
pixel data is only in the eight most significant bits of each word, but each
character supports up to 16 words. If the font needs to be changed on the fly
the CPU must store new data bytes at unpacked word intervals, as unpacking is
only automatic for LowRes 8 x 8 characters.
For ease of addressing the number of rows in each character should be a power
of two even if the number of rows used is not - e.g. 16 for 10, 12 or 16 pixel
tall characters, and eight for characters up to 8 pixels tall.
The order of characters corresponds to the character code from 0 to 255, and
need not be standard ASCII - it could be a variant like PET or TRS-80 ASCII or
something entirely different, such as ZX-80 or ZX-81 character codes. You can
switch between two fonts at the same Chip address MOD 65536 with just two
POKEs to the copper list, setting BLTAPT.H and BPLBPT.H to point to the
required page.
Bitplane sizes: 12K for 64x16 characters of 8x12 pixels each (HiRes 512 x 192)
8000 bytes for 40 x 25 8 x 8 pixel characters (LoRes 320 x 200)
A conventional Amiga bit map with one word for 16 pixels and lines consecutive
in memory. Allow for HeadLines and border pixels, if any, adding to the size of
the bitplane. There is a gap of 128 bytes at the end of the bitplane before the
font data starts.
Character Map size: 1K to 2K typically.
One byte for each character to be displayed, as a linear array with no gaps
between lines, e.g. the data for the second line of a 32 column x 16 line
screen starts with the 33rd byte. These bytes are shifted by four or five
places and inserted into the Copper List. In modes with no more than 1024
characters this is automatically unpacked into the Copper list before each new
field is displayed.
Copper List: A few hundred bytes of overhead + 20 bytes per character to blit
This is the clever bit. It contains anything up to 45K of Copper instructions
which must be executed every field (i.e. 50 times per second). These start by
setting up the display, but most of their effort goes into programming the
blitter to read the font for each byte in the character map and copy it to the
correct place in the Bit Map. Optional coloured stripes can show the time when
the copper is busiest and confirm beam avoidance without double buffering.
If automatic font expansion is in use then the blitter unpacks the 8 x 8
pixel font patterns into 8 x 16 bit words before it starts to blit characters.
Unpacking is performed in two passes, ascending and descending. The blitter
avoids hogging the bus (not 'nasty') so the CPU can finish off font writes
without falling behind the beam, at least during the ascending pass. If it's
still writing during the descending pass, those updates will not appear in the
unpacked font till the next field.
The blitter is switched into 'nasty' mode for the individual HiRes character
blits, which are short and well spaced so the CPU can get through between them
- although it will have to wait much more than if it got its writes done
earlier in the field. In general, the earlier the better.